<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<title>EaselJS Tutorial: Mouse Interaction</title>
	<link href="../shared/tutorial.css" rel="stylesheet" type="text/css">
	<script src="../shared/tutorial.js"></script>
	
	<!-- SyntaxHighlighter-->
	<script src="../shared/SyntaxHighlighter/shCore.js"></script>
	<script src="../shared/SyntaxHighlighter/shBrushJScript.js"></script>
	<script src="../shared/SyntaxHighlighter/shBrushXml.js"></script>
	<link href="../shared/SyntaxHighlighter/shCore.css" rel="stylesheet" type="text/css">
	<link href="../shared/SyntaxHighlighter/shThemeCreateJS.css" rel="stylesheet" type="text/css">
</head>
	
<body onLoad="initTutorial();">
	<article>
		<header>
			<h1>EaselJS: Mouse Interaction</h1>
			<p>
				<strong>Synopsis:</strong> Learn about mouse events on display objects and the stage.<br>
				<strong>Topics:</strong> MouseEvent, click, dblclick, mouseover, mouseout, mousemove, mousedown, mouseup, enableMouseOver, drag and drop, mouseMoveOutside<br>
				<strong>Target:</strong> EaselJS v0.6.0
			</p>
		</header>
		
		<section>
			<header>
				<h2>The Basics</h2>
			</header>
			<p>
				At its core, the EaselJS mouse interaction model is very simple to use - just assign a function handler for one of the mouse events on a display object:
			<textarea class="brush: js;" readonly>
circle.addEventListener("click", function(event) { alert("clicked"); })
			</textarea>
			</p>
			<iframe src="basic.html" class="demo" longDesc="the onClick handler" width="100%" height="220px"></iframe>
			<p>
				There are a number of events you can listen for on display objects: <code>click</code>, <code>mousedown</code>, <code>mouseup</code>, </code><code>dblclick</code>, <code>mouseover</code>, and <code>mouseout</code>.
			</p>
			<p>
				The latter two events have some overhead associated with them, so you need to enable them with <code>stage.enableMouseOver(frequency)</code>. The <code>frequency</code> parameter indicates how many times per second EaselJS should calculate what is currently under the pointer. A higher number is more responsive, but also more computationally expensive. It defaults to 20 times per second.
			</p>
		</section>
		
		<section>
			<header>
				<h2>MouseEvent</h2>
			</header>
			<p>
				When a mouse handler is triggered, it is called with a single parameter holding a MouseEvent instance. You can use this object to see what <code>type</code> of event it was, what the <code>target</code> was, get access to the <code>nativeEvent</code> object it was based on, and to check the pointer's <code>stageX</code> and <code>stageY</code> coordinates.
			<textarea class="brush: js;" readonly>
circle.addEventListener("click", function(evt) {
	alert("type: "+evt.type+" target: "+evt.target+" stageX: "+evt.stageX);
});
			</textarea>
			</p>
			<iframe src="events.html" class="demo" longDesc="demonstrating the different mouse event types on display objects" width="100%" height="220px"></iframe>
		</section>
		
		<section>
			<header>
				<h2>Containers</h2>
			</header>
			<p>
				When you assign a mouse event handler on a <code>Container</code> instance, it will block all mouse events to its children, even if they have their own listeners.
			</p>
			<p>
				The example below has a "button", which is a <code>Container</code> instance containing two children: a background shape, and a text label.
                All three of these display objects have <code>click</code> handlers, but if you click the button, only its handler is called.
			</p>
			<iframe src="container.html" class="demo" longDesc="mouse event handlers on containers" width="100%" height="120px"></iframe>
			<p>
				If you edit the code for container.html to remove the <code>click</code> handler on button, the handlers on background and label will be active.
			</p>
			<p>
				You can also block mouse events to children without assigning a handler by setting <code>mouseChildren</code> to <code>false</code>.
			<textarea class="brush: js;" readonly>
myContainer.mouseChildren = false;
			</textarea>
			</p>
			<p>
				Similarly, you can disable mouse events on any display object without removing its handlers by setting <code>mouseEnabled</code> to <code>false</code>.
			<textarea class="brush: js;" readonly>
circle.addEventListener("click", function() { alert("Clicked!"); });
circle.mouseEnabled = false;
			</textarea>
		</section>
		
		<section>
			<header>
				<h2>hitArea</h2>
			</header>
			<p>
				Normally, EaselJS will calculate mouse hits on a display object based on its visible, non-transparent pixels. This usually works pretty well, but there may be cases where you want to define a hit target that is different than what is displayed on screen.
			</p>
			<p>
				To do this, you can assign any other display object to be the <code>hitArea</code> for your object. It does not need to be on the display list, and will not be visible, but it will be used for the hit test instead.
			</p>
			<p>
				Hit area display objects are used within the coordinate system (ie. concatenated transformation) of their owner, and as such you can reuse the same display object as the <code>hitArea</code> of multiple objects.
			</p>
			<iframe src="hitArea.html" class="demo" longDesc="mouse event handlers on containers" width="100%" height="170px"></iframe>
			<p>
				Notice how in this demo, as you roll over the red text, it only registers a hit when the pointer is over a non-transparent pixel, whereas the blue text uses the rectangular <code>hitArea</code> to calculate the hit.
			</p>
		</section>
			
		<section>
			<header>
				<h2>Stage mouse events</h2>
			</header>
			<p>
				If you assign a normal mouse event handler to the stage, it will block mouse events to all of its children. Also, just like every other display object, you will only get events when the mouse is over a non-transparent pixel.
			</p>
			<p>
				Stage has a few special mouse events that come in handy for responding to general mouse interactions anywhere within your canvas. <code>stagemousedown</code>, <code>stagemouseup</code> and <code>stagemousemove</code> are called any time a relevant mouse interaction happens anywhere on the canvas.
			<textarea class="brush: js;" readonly>
stage.addEventListener("stagemousedown", function(evt) {
	alert("the canvas was clicked at "+evt.stageX+","+evt.stageY);
})
			</textarea>
			<p>
				The following demo demonstrates using these events to let you finger paint on the canvas:
			</p>
			<iframe src="stage.html" class="demo" longDesc="using stagemousedown, stagemouseup & stagemousemove." width="100%" height="220px"></iframe>
			<p>
				By default, you will stop getting <code>stagemousemove</code> events whenever the pointer is outside of the canvas. You can check of this has happened with <code>stage.mouseInBounds</code>.
			</p>
			<p>
				If you'd like to keep getting <code>stagemousemove</code> events when the pointer leaves the canvas, just set <code>mouseMoveOutside</code> to <code>true</code>. The <code>stageX</code> & <code>stageY</code> properties of <code>MouseEvent</code> will always return a value normalized to within your stage bounds, but you can use <code>rawX</code> and <code>rawY</code> to get values that haven't been normalized (this can cause errors if you aren't careful).
			<textarea class="brush: js;" readonly>
stage.mouseMoveOutside = true;
stage.onMouseMove = function(evt) {
	console.log("stageX/Y: "+evt.stageX+","+evt.stageY); // always in bounds
	console.log("rawX/Y: "+evt.rawX+","+evt.rawY); // could be < 0, or > width/height
}
			</textarea>
			</p>
		</section>
		
		<section>
			<header>
				<h2>Drag and drop</h2>
			</header>
			<p>
				EaselJS makes drag and drop functionality very easy to implement. When an <code>click</code> handler is
                called, the <code>MouseEvent</code> that is passed to it has two special mouse handlers of its own,
                <code>mousemove</code> and <code>mouseup</code>.
			</p>
			<p>
				These handlers work exactly the same as their equivalents on <code>Stage</code> with one major difference -
                they are only active until the user releases the pointer. It sounds a little strange, but it's really simple to use.
			</p>
			<textarea class="brush: js;" readonly>
circle.addEventListener("mousedown", function(evt) {
	// add handlers directly to the event object:
	evt.addEventListener("mousemove", function(evt) {
		evt.target.x = evt.stageX;
		evt.target.y = evt.stageY;
	});
	evt.addEventListener("mouseup", function(evt) { console.log("up"); })
})
			</textarea>
			<p>
				Check out the source for the demo below for a simple example of this in action. It's also a great place
                to test out the <code>mouseMoveOutside</code> property.
			</p>
			<iframe src="drag.html" class="demo" longDesc="implementing drag and drop" width="100%" height="220px"></iframe>
		</section>
		
		<section>
			<header>
				<h2>Other useful APIs</h2>
			</header>
			<p>
				Other methods that are relevant to advanced mouse interactions are:<ul>
					<li> <code>Container.getObjectUnderPoint()</code> returns the top most display object under the specified point.
					<li> <code>Container.getObjectsUnderPoint()</code> returns all display objects under the specified point.
					<li> <code>DisplayObject.hitTest()</code> returns true if the specified point in the display object is non-transparent.
				</ul>
				Check out the API documentation and the HitTest tutorial for more information.
			</p>
		</section>
		
	</article>
</body>
</html>
